The present invention relates generally to systems running a physics simulation within the context of a main application. In one embodiment, the present invention relates to systems, such as Personal Computers (PCs) and game consoles, comprising a physics co-processor, or a so-called Physics Processing Unit (PPU). Several exemplary embodiments of a PPU-enabled system are disclosed in U.S. patent application Ser. No. 10/715,370 filed Nov. 19, 2003 and Ser. No. 10/839,155 filed May 6, 2004.
In response to the growing appetite for physics-based animations, software-based physics engines have conventionally been added to, or associated with the program code implementing a main application. Indeed, a market currently exists for “physics middleware”—specialty software directed to the generation and incorporation of physics-based data within a main application. Companies like HAVOK and MathEngine have developed this type of specialty software that may be called by a main application to better incorporate natural looking, physics-based animations into the main application.
Conventional software-based physics engines allow programmers increased latitude to assign virtual mass and coefficients of friction to objects animated within the execution of the main application. Similarly, virtual forces, impulses, and torques may be applied to objects. In effect, software-based physics engines provide programmers with a library of procedures to simplify the visual creation of scenes having physics-based interaction between objects.
Unfortunately, as has been previously documented, the growing appetite for animated realism can not be met by merely providing additional specialty software into a single execution thread, thereby layering upon the CPU additional processing requirements. And this is true regardless of the relative sophistication of the specialty software.
In the discussion that follows, the term “physics engine” describes a range of software and/or hardware products adapted to provide a main application with the ability to simulate various kinds of physical or physics-based properties and/or effects, such as rigid-body simulation, fluid simulation, and/or cloth simulation to name just a few examples. Conventional, physics middleware is one type of physics engine. As currently implemented, conventional physics middleware establishes a software library adapted to run on the same processor as a main application in a single processor system.
However, systems having multiple processors, multiple execution threads, and/or multiple cores are becoming increasingly common. Additionally, special purpose add-on processors or subsystems, such as the PPU referenced above are also becoming commercially available. Thus, a physics engine implemented within the context of one of these systems will be a very different in its nature from physics engines conventionally implemented using physics middleware.
For example, one or more of the additional processors, cores, execution threads, or a separately provided PPU may be used to run the physics simulation and thus implement a physics engine. This is particularly true where significant additional processing power is required to execute a simulation comprising larger, more complex scenes including a greater numbers of actors having more detailed geometry.
However implemented, physics engines are typically associated with an Application Programming Interface (API) through which at least a main application may communicate with the physics engine. The physics engine API may be provided as part of the main application, as part of an Operating System (OS) associated with one or more computational platforms, and/or within the physics simulation code. By making calls to procedures identified in the physics engine API, the main application may configure a simulation, configure physics data (e.g., static data, parameters, and/or state information) for the simulation, advance the simulation in time (i.e., cause the physics engine to compute the state of the simulation at a next step in time), and/or query various state information, such as position and applied forces to actors in the simulation, etc. Calls to procedures identified in the physics engine API, among many other possible calls, are typically initiated by the main application.
The term “call” as variously used to broadly describes any interaction by which one piece of software causes the initiation, execution, retrieval, storage, indexing, update, etc., of another piece of software, or the execution of another piece of software using resources associated with a computational platform, typically including firmware and/or hardware. The term “run” describes any process in which hardware resources associated with a computational platform perform an operation under the direction (directly or indirectly) of a software resource.
Frequently, a main application may wish (or require) notification related to a particular event occurring in a simulation. For example, a specific physics data value to-be-derived by the simulation code running on the physics engine may be required by the main application in order to initiate a particular procedure. An “event” may be defined in terms of physics data (or other data) generation and/or availability, one or more simulation actor(s) characteristic(s) and/or interaction(s), an execution and/or temporal point in the simulation or main application, a user input, etc. While it is certainly possible for the main application to repeatedly query the physics engine after each simulation time step in relation to the event of interest, many physics engines such as conventional physics middleware, provide a more efficient callback registration mechanism.
Consider the example shown in FIG. 1. In this example, a main application 1 calls a physics engine 2 through an associated physics engine API 3 in relation to a particular callback procedure associated with one or more events. In this regard, main application 1 is said to “register the callback.” There are many possible ways to register a callback are known to those skilled in the art, but one example will serve for the current description.
In order to register a callback, main application 1 identifies a callback procedure 5 associated with the event of interest and calls physics engine 2 through physics engine API 3. Callback procedure 5 is typically part of the main application code block but may also be separately provided. Assuming the use of a programming language such as C or C++, callback procedure 5 may be registered with physics engine 2 by communicating a procedure pointer value (e.g., an address vector) identifying the location of callback procedure 5 in a memory associated with the main application. This procedure pointer value may be stored in any reasonable memory or register 7 accessible by physics engine 2.
Events are known to and able to be identified by simulation 6. Thus, when a possible event of interest occurs during execution of simulation 6, or has occurred during a given simulation time step, callback register 7 is queried to determine whether a corresponding callback procedure has been registered. Where a corresponding callback procedure is found, simulation code 6 calls callback procedure 5 using information provided by the callback procedure registration. With data (e.g., physics data) provided by physics engine 2, callback procedure 5 is able to run, and the main application is accordingly able to progress.
This type of callback mechanism works well, so long as the main application and simulation are running in the single execution thread. This is true regardless of the type of computational platform (e.g., processor, core, PPU, etc.) actually executing the thread. However, in a system running a simulation in parallel with, or asynchronously to, a main application thread, a more sophisticated callback mechanism is required. In other words, parallel (whether wholly or in part) execution of application and simulation threads has the potential to create serious problems with callback procedures. As the simulation proceeds on one execution thread, the main application proceeds on another execution thread. Thus, a callback procedure registration that potentially looks forward to a future occurring event, must account for the possibility that the main application and/or the simulation may be in an indeterminate state relative to the information state assumed by the callback registration when the event finally occurs.
Clearly, parallel/asynchronous execution of a main application and simulation requires greater sophistication in the definition and execution of a related callback procedure.